<!DOCTYPE html>
<html>

<head>
    <title>extrudeline test</title>
    <script type="text/javascript" src="https://unpkg.com/dat.gui@0.7.6/build/dat.gui.min.js"></script>
    <link type="text/css" rel="stylesheet" href="https://unpkg.com/maptalks/dist/maptalks.css">
    <script type="text/javascript" src="https://unpkg.com/maptalks/dist/maptalks.js"></script>
    <script type="text/javascript" src="https://unpkg.com/three@0.138.0/build/three.min.js"></script>
    <script type="text/javascript" src="https://unpkg.com/lz-string@1.4.4/libs/lz-string.min.js"></script>
    <script type="text/javascript"
        src="https://unpkg.com/three@0.138.0/examples/js/libs/stats.min.js"></script>
    <script type="text/javascript" src="https://unpkg.com/maptalks.three@latest/dist/maptalks.three.js"></script>
    <!-- <script type="text/javascript" src="buildings.js"></script> -->
    <style>
        html,
        body {
            margin: 0px;
            height: 100%;
            width: 100%;
        }

        #map {
            width: 100%;
            height: 100%;
            background-color: #000;
        }
    </style>
</head>

<body>
    <div id="map"></div>
    <script>
        var map = new maptalks.Map("map", {
            "center": [-73.94112755939187, 40.63313710084762], "zoom": 14, "pitch": 47.200000000000045, "bearing": -0.6000000000002501,
            centerCross: true,
            doubleClickZoom: false,
            baseLayer: new maptalks.TileLayer('tile', {
                urlTemplate: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
                subdomains: ['a', 'b', 'c', 'd'],
                attribution: '&copy; <a href="http://osm.org">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/">CARTO</a>'
            })
        });
        // the ThreeLayer to draw buildings
        var threeLayer = new maptalks.ThreeLayer('t', {
            forceRenderOnMoving: true,
            forceRenderOnRotating: true
            // animation: true
        });
        threeLayer.prepareToDraw = function (gl, scene, camera) {
            stats = new Stats();
            stats.domElement.style.zIndex = 100;
            document.getElementById('map').appendChild(stats.domElement);

            var light = new THREE.DirectionalLight(0xffffff);
            light.position.set(0, -10, 10).normalize();
            scene.add(light);

            load();
        };
        threeLayer.addTo(map);


        var material = new THREE.MeshPhongMaterial({ color: 0x00ffff, transparent: true });
        var highlightmaterial = new THREE.MeshBasicMaterial({ color: 'yellow', transparent: true });
        var lines = [], selectMesh = [];
        var idx = 0, max = 106;
        function load() {
            fetch(`./data/nyroad/nyroad${idx}.geojson`).then(function (res) {
                return res.json();
            }).then(function (geojson) {
                var lineStrings = maptalks.GeoJSON.toGeometry(geojson);
                var timer = 'generate line time';
                console.time(timer);
                lineStrings.forEach(lineString => {
                    lineString.setProperties({ altitude: 0, width: 3, height: 1 });
                });
                const mesh = threeLayer.toExtrudeLines(lineStrings, { interactive: false, minZoom: 11 }, material);
                lines.push(mesh);
                threeLayer.addMesh(mesh);
                console.log('lines.length:', lines.length);
                console.timeEnd(timer);

                mesh.setToolTip('hello', {
                    showTimeout: 0,
                    eventsPropagation: true,
                    dx: 10
                });

                //infowindow test
                mesh.setInfoWindow({
                    content: 'hello world',
                    title: 'message',
                    animationDuration: 0,
                    autoOpenOn: false
                });

                //event test
                ['click', 'mousemove', 'empty', 'mouseout', 'mouseover', 'mousedown', 'mouseup', 'dblclick', 'contextmenu'].forEach(function (eventType) {
                    mesh.on(eventType, function (e) {
                        // console.log(e.type);
                        const select = e.selectMesh;
                        if (e.type === 'empty' && selectMesh.length) {
                            threeLayer.removeMesh(selectMesh);
                            selectMesh = [];
                        }

                        let data, baseObject;
                        if (select) {
                            data = select.data;
                            baseObject = select.baseObject;
                            if (baseObject && !baseObject.isAdd) {
                                baseObject.setSymbol(highlightmaterial);
                                threeLayer.addMesh(baseObject);
                                selectMesh.push(baseObject);
                            }
                        }


                        if (selectMesh.length > 20) {
                            threeLayer.removeMesh(selectMesh);
                            selectMesh = [];
                        }


                        // override tooltip
                        if (e.type === 'mousemove' && data) {
                            const height = JSON.stringify(data.getProperties());
                            const tooltip = this.getToolTip();
                            tooltip._content = `property:${height}`;
                        }
                        //override infowindow
                        if (e.type === 'click' && data) {
                            const height = JSON.stringify(data.getProperties());
                            const infoWindow = this.getInfoWindow();
                            infoWindow.setContent(`property:${height}`);
                            if (infoWindow && (!infoWindow._owner)) {
                                infoWindow.addTo(this);
                            }
                            this.openInfoWindow(e.coordinate);

                        }
                    });
                });
                if (idx < max) {
                    setTimeout(() => {
                        idx++;
                        load();
                    }, 10);
                } else {
                    initGui();
                    animation();
                }
            });
        }

        function animation() {
            // layer animation support Skipping frames
            threeLayer._needsUpdate = !threeLayer._needsUpdate;
            if (threeLayer._needsUpdate) {
                threeLayer.redraw();
            }
            stats.update();
            requestAnimationFrame(animation);
        }


        function initGui() {
            var params = {
                add: true,
                color: 0x00ffff,
                show: true,
                opacity: 1,
                altitude: 0,
                interactive: false
            };
            var gui = new dat.GUI();
            gui.add(params, 'add').onChange(function () {
                if (params.add) {
                    threeLayer.addMesh(lines);
                } else {
                    threeLayer.removeMesh(lines);
                }
            });
            gui.addColor(params, 'color').name('line color').onChange(function () {
                material.color.set(params.color);
                lines.forEach(function (mesh) {
                    mesh.setSymbol(material);
                });
            });
            gui.add(params, 'opacity', 0, 1).onChange(function () {
                material.opacity = params.opacity;
                lines.forEach(function (mesh) {
                    mesh.setSymbol(material);
                });
            });
            // gui.add(params, 'show').onChange(function () {
            //     lines.forEach(function (mesh) {
            //         if (params.show) {
            //             mesh.show();
            //         } else {
            //             mesh.hide();
            //         }
            //     });
            // });
            gui.add(params, 'altitude', 0, 300).onChange(function () {
                lines.forEach(function (mesh) {
                    mesh.setAltitude(params.altitude);
                });
            });
            gui.add(params, 'interactive').onChange(function () {
                lines.forEach(function (mesh) {
                    mesh.options.interactive = params.interactive;
                });
            });
        }
    </script>
</body>

</html>